// 实现语音识别子服务
#include <brpc/server.h>
#include "asr.hpp"      // 语音是被模块封装
#include "etcd.hpp"     // 服务注册模块封装
#include "logger.hpp"   // 日志模块封装
#include "speech.pb.h"  //protobuf框架代码

namespace wufan_im{
//1. 继承与EchoService创建一个子类, 并实现rpc调用的业务功能
class SpeechServiceImpl : public bite_im::SpeechService{     //EchoService类是远程调用rpc服务的类 - 就是真正进行sum计算的
    public:
    SpeechServiceImpl(wufan_im::ASRClient::ptr asr_client)
    :_asr_client(asr_client)
    {}
    // 重写这个虚函数
    //RpcController: 返回结果是成功或失败   
    //request客户端的请求   response服务器要构造的响应
    //Closure: 大格局理解 服务端是异步执行的, 将Response的响应设置完了, 再调用run函数, 告诉服务器可以发给客户端响应了
    void SpeechRecognition(google::protobuf::RpcController* controller, const ::bite_im::SpeechRecognitionReq* request,
              ::bite_im::SpeechRecognitionRsp* response, ::google::protobuf::Closure* done)
    {
        //防止程序员忘记最后调用run函数, 所以用智能指针来管理起来
        brpc::ClosureGuard rpc_guard(done);
        
        // 1. 取出请求中的语音数据
        // 2. 调用语音sdk模块进行语音识别, 得到响应
        std::string err;
        std::string res = _asr_client->recognize(request->speech_content(), err);
        if (res.empty()) {
            LOG_ERROR("{} 语音识别失败! ", request->request_id());
            response->set_request_id(request->request_id());
            response->set_success(false);
            response->set_errmsg("语音识别失败:" + err);
            return;
        }
        // 3. 组织响应
        response->set_request_id(request->request_id());
        response->set_success(true);
        response->set_recognition_result(res);
        // done->Run()      如果不写上面的guard, 则需要加上这句话
    }
    private:
        wufan_im::ASRClient::ptr _asr_client;
};

//我们要保证make_asr和make_reg函数必须要在调用start函数之前调用, 
//所以我们就要使用一个设计者模式，建造者模式，不让用户乱去构造，而让我们去构造
class SpeechServer{
    public:
        using ptr = std::shared_ptr<SpeechServer>;
        SpeechServer(const wufan_im::ASRClient::ptr asr_client, const wufan_im::Registry::ptr& reg_client,
            std::shared_ptr<brpc::Server>& server)
        :_asr_client(asr_client), _reg_client(reg_client), _rpc_server(server)
        {}
        // 搭建RPC服务器, 并启动服务器
        void start(){
            _rpc_server->RunUntilAskedToQuit();
        }
    private:
        wufan_im::ASRClient::ptr _asr_client;       // 语音通信的客户端
        wufan_im::Registry::ptr _reg_client;        // 服务注册的客户端
        std::shared_ptr<brpc::Server> _rpc_server;  // rpc提供服务的服务端
};


//简化复杂对象的创建过程
//建造者模式将一个"复杂对象"的构建过程分解为多个简单步骤，并将这些步骤封装在独立的建造者类中。
//这样，用户只需要按照指定的步骤来构建对象，而无需了解对象内部的具体实现细节。
//这大大简化了复杂对象的创建过程，使得代码更加清晰和易于理解。
// SpeechServerBuild就是来专门构造SpeechServer类的, 我们并不去构造SpeechServer类
class SpeechServerBuilder{
    public:
        // 构造语音识别客户端对象
        void make_asr_object(const std::string& app_id, const std::string& api_key, const std::string& secret_key) {
            _asr_client = std::make_shared<wufan_im::ASRClient>(app_id, api_key, secret_key);
        }
        // 用于构造服务注册客户端对象
        void make_reg_object(const std::string& reg_host, const std::string& service_name, const std::string& access_host) {
            _reg_client = std::make_shared<wufan_im::Registry>(reg_host);
            _reg_client->registry(service_name, access_host);
        }
        void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
            if (!_asr_client) {
                LOG_ERROR("还未初始化语音是被模块! ");
                abort();
            }
            _rpc_server = std::make_shared<brpc::Server>();
            // SpeechServiceImpl speech_service(_asr_client);  注意这里, 不能是栈对象
            // shared_ptr<SpeechServiceImpl> speech_service = make_shared<SpeechServiceImpl>(_asr_client);
            SpeechServiceImpl* speech_service = new SpeechServiceImpl(_asr_client);
            int ret = _rpc_server->AddService(speech_service, brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
            if (ret == -1) {
                LOG_ERROR("添加Rpc服务失败!");
                abort();
            }
            brpc::ServerOptions options;
            options.idle_timeout_sec = timeout;
            options.num_threads = num_threads;
            ret = _rpc_server->Start(port, &options);
            if (ret == -1) {
                LOG_ERROR("服务启动失败! ");
                abort();
            }
        }
        SpeechServer::ptr build() {
            if (!_asr_client) {
                LOG_ERROR("还未初始化语音是被模块! ");
                abort();
            }
            if (!_reg_client) {
                LOG_ERROR("还未初始化注册模块! ");
                abort();
            }
            if (!_rpc_server) {
                LOG_ERROR("还未初始化RPC服务器模块! ");
                abort();
            }
            SpeechServer::ptr server = std::make_shared<SpeechServer>(_asr_client, _reg_client, _rpc_server);
            return server;
        }
    private:
        wufan_im::ASRClient::ptr _asr_client;       // 语音通信的客户端
        wufan_im::Registry::ptr _reg_client;        // 服务注册的客户端
        std::shared_ptr<brpc::Server> _rpc_server;  // rpc提供服务的服务端
};
}


// //实现语音识别子服务
// #include <brpc/server.h>
// #include <butil/logging.h>

// #include "asr.hpp"      // 语音识别模块封装
// #include "etcd.hpp"     // 服务注册模块封装
// #include "logger.hpp"   // 日志模块封装
// #include "../build/speech.pb.h"  // protobuf框架代码

// namespace wufan_im{
// class SpeechServiceImpl : public bite_im::SpeechService {
//     public:
//         SpeechServiceImpl(const wufan_im::ASRClient::ptr &asr_client):
//             _asr_client(asr_client){}
//         ~SpeechServiceImpl(){}
//         void SpeechRecognition(google::protobuf::RpcController* controller,
//                        const ::bite_im::SpeechRecognitionReq* request,
//                        ::bite_im::SpeechRecognitionRsp* response,
//                        ::google::protobuf::Closure* done) {
//             LOG_DEBUG("收到语音转文字请求！");
//             brpc::ClosureGuard rpc_guard(done);
//             //1. 取出请求中的语音数据
//             //2. 调用语音sdk模块进行语音识别，得到响应
//             std::string err;
//             std::string res = _asr_client->recognize(request->speech_content(), err);
//             if (res.empty()) {
//                 LOG_ERROR("{} 语音识别失败！", request->request_id());
//                 response->set_request_id(request->request_id());
//                 response->set_success(false);
//                 response->set_errmsg("语音识别失败:" + err);
//                 return;
//             }
//             //3. 组织响应
//             response->set_request_id(request->request_id());
//             response->set_success(true);
//             response->set_recognition_result(res);
//         }
//     private:
//         wufan_im::ASRClient::ptr _asr_client;
// };

// class SpeechServer {
//     public:
//         using ptr = std::shared_ptr<SpeechServer>;
//         SpeechServer(const wufan_im::ASRClient::ptr asr_client, 
//             const wufan_im::Registry::ptr &reg_client,
//             const std::shared_ptr<brpc::Server> &server):
//             _asr_client(asr_client),
//             _reg_client(reg_client),
//             _rpc_server(server){}
//         ~SpeechServer(){}
//         //搭建RPC服务器，并启动服务器
//         void start() {
//             _rpc_server->RunUntilAskedToQuit();
//         }
//     private:
//         wufan_im::ASRClient::ptr _asr_client;
//         wufan_im::Registry::ptr _reg_client;
//         std::shared_ptr<brpc::Server> _rpc_server;
// };

// class SpeechServerBuilder {
//     public:
//         //构造语音识别客户端对象
//         void make_asr_object(const std::string &app_id,
//             const std::string &api_key,
//             const std::string &secret_key) {
//             _asr_client = std::make_shared<wufan_im::ASRClient>(app_id, api_key, secret_key);
//         }
//         //用于构造服务注册客户端对象
//         void make_reg_object(const std::string &reg_host,
//             const std::string &service_name,
//             const std::string &access_host) {
//             _reg_client = std::make_shared<wufan_im::Registry>(reg_host);
//             _reg_client->registry(service_name, access_host);
//         }
//         //构造RPC服务器对象
//         void make_rpc_server(uint16_t port, int32_t timeout, uint8_t num_threads) {
//             if (!_asr_client) {
//                 LOG_ERROR("还未初始化语音识别模块！");
//                 abort();
//             }
//             _rpc_server = std::make_shared<brpc::Server>();
//             SpeechServiceImpl *speech_service = new SpeechServiceImpl(_asr_client);
//             int ret = _rpc_server->AddService(speech_service, 
//                 brpc::ServiceOwnership::SERVER_OWNS_SERVICE);
//             if (ret == -1) {
//                 LOG_ERROR("添加Rpc服务失败！");
//                 abort();
//             }
//             brpc::ServerOptions options;
//             options.idle_timeout_sec = timeout;
//             options.num_threads = num_threads;
//             ret = _rpc_server->Start(port, &options);
//             if (ret == -1) {
//                 LOG_ERROR("服务启动失败！");
//                 abort();
//             }
//         }
//         SpeechServer::ptr build() {
//             if (!_asr_client) {
//                 LOG_ERROR("还未初始化语音识别模块！");
//                 abort();
//             }
//             if (!_reg_client) {
//                 LOG_ERROR("还未初始化服务注册模块！");
//                 abort();
//             }
//             if (!_rpc_server) {
//                 LOG_ERROR("还未初始化RPC服务器模块！");
//                 abort();
//             }
//             SpeechServer::ptr server = std::make_shared<SpeechServer>(
//                 _asr_client, _reg_client, _rpc_server);
//             return server;
//         }
//     private:
//         wufan_im::ASRClient::ptr _asr_client;
//         wufan_im::Registry::ptr _reg_client;
//         std::shared_ptr<brpc::Server> _rpc_server;
// };
// }